package model;

import java.util.Hashtable;
import java.util.LinkedList;
import java.util.List;

import math.Expression;
import model.altarica_fields.Event;
import model.altarica_fields.Sync;
import model.altarica_fields.Trans;
import model.altarica_fields.UpdateExpression;
import model.altarica_fields.Var;

public class AltaRicaNode {


	private String name;
	
	private Hashtable<String, Var> states;
	private Hashtable<String, Var> flow;
	private Hashtable<String, Event> events;
	private List<UpdateExpression> init;
	private List<Trans> trans_list;
	private List<Expression> assert_list;
	private Hashtable<String, AltaRicaNode> subs;
	private LinkedList<Sync> sync_list;
	
	public AltaRicaNode() {
		
		this.name = null;
		this.states = null;
		this.flow = null;
		this.events = null;
		this.init = null;
		this.trans_list = null;
		this.assert_list = null;
		this.subs = new Hashtable<String, AltaRicaNode>();
		this.sync_list = new LinkedList<Sync>();
	}
	
	public AltaRicaNode(String name) {
		
		this.name = name;
		
		this.states = null;
		this.flow = null;
		this.events = null;
		this.init = null;
		this.trans_list = null;
		this.assert_list = null;
		this.subs = new Hashtable<String, AltaRicaNode>();
	}
	
	public void setName(String name) {
		
		this.name = name;
	}
	
	public String getName() {
		
		return this.name;
	}
	
	public void setStates(Hashtable<String, Var> states) {
		
		this.states = states;
	}
	
	public void setFlows(Hashtable<String, Var> flow) {
		
		this.flow = flow;
	}
	
	public void setEvents(Hashtable<String, Event> events) {
		
		this.events = events;
	}

	public Var getStateVar(String str) {
		
		return states.get(str);
	}
	
	public Var getFlowVar(String str) {
		
		return flow.get(str);
	}
	
	public Event getEvent(Event e) {
		
		return getEvent(e.getId());
	}
	
	public Event getEvent(String id) {
		
		return events.get(id);
	}
	
	public Var getVar(String str) {
		
		Var var = null;
		
		var = getStateVar(str);
		
		if (var == null)
			var = getFlowVar(str);
		
		return var;
	}
	
	public void setInit(List<UpdateExpression> list) {
		
		this.init = list;
	}
	
	public List<UpdateExpression> getInit() {
		
		return this.init;
	}
	
	public void setTrans(List<Trans> trans) {
		
		this.trans_list = trans;
	}
	
	public List<Trans> getTrans() {
		
		return this.trans_list;
	}
	
	public void setAsserts(List<Expression> assert_list) {
		
		this.assert_list = assert_list;
	}
	
	public List<Expression> getAsserts() {
		
		return this.assert_list;
	}
	
	public void addSub(String id, AltaRicaNode node) {
		
		this.subs.put(id, node);
	}
	
	public AltaRicaNode getSub(String id) {
		
		return this.subs.get(id);
	}
	
	public void addSync(Sync sync) {
		
		this.sync_list.addLast(sync);
	}
	
	public String toString() {
		
		String str = new String("node " + name + "\n");
		
		str += "   sub\n";
		
		for (String s : subs.keySet())
			str += "     " + s + " : " + subs.get(s).getName() + ";\n";
		
		str += "   state\n";

		for (Var s : states.values())
			str += "     " + s + ";\n";
		
		str += "   flow\n";
		
		for (Var s : flow.values())
			str += "     " + s + ";\n";
		
		str += "   event\n";
		
		for (Event e : events.values()) {
			if (e.isEpsilon() == false) {
				str += "     " + e.getId() + "; \n";
			}
			for (Event a : e.getLessEvents()) {
				str += "     " + a.getId() + " < " + e.getId() + "; \n";
			}
		}
		
		str += "   trans\n";
		for (Trans t : trans_list)
			str += "     " + t.toString() + ";\n";
				
		str += "   sync\n";
		
		for (Sync sync : sync_list) {
			
			str += "     " + sync.toString() + ";\n";
		}
		
		str += "   init\n";
		for (UpdateExpression u : init)
			str += "     " + u + ";\n" ;
		
		str += "   assert\n";
		for (Expression e : assert_list)
			str += "     " + e + ";\n" ;
				
		str += "edon\n";
		
		return str;
	}
}
